package jlib.component.core
{
	import flash.display.Bitmap;
	import flash.display.LineScaleMode;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flash.text.engine.RenderingMode;
	
	import jlib.core.geom.Bound;
	import jlib.utils.TextFieldUtil;
	import flash.display.BitmapData;
	
	
	/**
	 * v 1.2 Refactory. 
	 * @author JongheePark 
	 */	
	public class LabelBox extends Sprite
	{
		protected var m_scaleX:Number, m_scaleY:Number;
		protected var m_textField:TextField;
		protected var m_textFieldBitmap:Background;
		protected var m_textFormat:TextFormat;
		
		protected var isOverRangeExpresstion:Boolean;
		protected var isInput:Boolean;
		
		protected var m_border:Border;
		protected var m_background:Background;
		protected var m_padding:Bound;
		
		protected var m_renderType:String;
		
		public function LabelBox($label:String="label"){
			buildDefault($label);
		}
		
		private function buildDefault($label:String): void
		{
			m_renderType = RenderType.VECTOR;
			m_textFieldBitmap = new Background();
			m_padding = new Bound();
			this.mouseChildren = false;
			m_background = new Background();
			m_border = new Border();
			m_textField = new TextField();
			m_textField.autoSize = 'left';
			m_textField.text = $label;
			checkSize();
			m_textField.autoSize = 'none';
			m_textField.selectable = false;
			m_textField.addEventListener(Event.SCROLL, dispatchEvent );
			setBorder(0);
			setRound(0);
			setFormat(new TextFormat(null,'12',0x000000));
			this.addEventListener(Event.ADDED_TO_STAGE, onStage );
			addChild(m_background);
			addChild(m_textField);
			addChild(m_border);
		}
		
		public function setRound($round:int): void 
		{
			m_border.setRound($round);
			m_background.setRound($round);
			update();
		}
		
		public function setSelectable($boolean:Boolean): void 
		{
			m_textField.selectable = $boolean;
		}
		
		public function setBackground(source:*): void {
			m_background.setSource(source);
			update();
		}
		
		public function setOverRangeExpresstion($boolean:Boolean): void 
		{
			isOverRangeExpresstion = $boolean;
		}
		
		public function setBorder($thickness:int=0, $color:uint=0x000000, $type:String='solid', $position:String='middle', $scaleMode:String = LineScaleMode.NONE, $dashSize:Number=3, $gapSize:Number=3): void
		{
			m_border.setThickness($thickness), m_border.setColor($color), m_border.setType($type), m_border.setPosition($position);
			m_border.setScaleMode($scaleMode), m_border.setDashSize($dashSize), m_border.setGapSize($gapSize);
			update();
		}
		
		private function onStage(e:Event): void
		{
			if(isInput) stage.addEventListener(KeyboardEvent.KEY_UP, checkTyping);
		}
		
		public function getRenderType(): String { return m_renderType; }
		
		public function setRenderType($type:String): void {
			m_renderType = $type;
			if(m_renderType == RenderType.BITMAP) {
				removeChild(m_textField);
				addChildAt(m_textFieldBitmap,1);
			}else {
				removeChild(m_textFieldBitmap);
				addChildAt(m_textField,1);
			}
		}
		
		public function italic($bool:Boolean=true): void {
			m_textFormat.italic = $bool;
		}
		
		public function bold($bool:Boolean=true): void {
			m_textFormat.bold = $bool;
			setFormat(m_textFormat);
		}
		
		public function getFilters():Array { return m_textField.filters; } 
		
		public function setFilters($filters:Array): void {
			m_textField.filters = $filters;
		}
		
		public function getFontColor(): int { return int(m_textFormat.color); }
		
		public function setFontColor($color:int): void {
			m_textFormat.color = $color;
			setFormat(m_textFormat);
		}
		
		public function getFontSize(): int { return int(m_textFormat.size); }
		
		public function setFontSize($size:int): void {
			m_textFormat.size = $size;
			setFormat(m_textFormat);
		}
		
		public function getFont(): String { return m_textFormat.font; }
		
		public function setFont($fontName:String): void {
			m_textFormat.font = $fontName;
			setFormat(m_textFormat);
		}
		
		public function getEmbedFonts(): Boolean { return m_textField.embedFonts; }
		public function setEmbedFonts($boolean:Boolean): void {
			m_textField.embedFonts = $boolean;
			checkSize();
			update();
		}
		
		public function getFormat(): TextFormat { return m_textFormat; }
		
		public function setFormat($textFormat:TextFormat, $start:int=-1, $end:int=-1): void {
			m_textFormat = $textFormat;
			m_textField.setTextFormat($textFormat, $start, $end);
			m_textField.defaultTextFormat = m_textFormat;
			checkSize();
			update();
		}
		
		public function setPass($boolean:Boolean): void {
			m_textField.displayAsPassword = $boolean;
		}
		
		public function setAlign($textFormatAlign:String, $start:int=-1, $end:int=-1): void
		{
			if(!m_textFormat) m_textFormat = new TextFormat(null,null,null,null,null,null,null,null,$textFormatAlign);
			else m_textFormat.align = $textFormatAlign;
			setFormat(m_textFormat, $start, $end);
		}
		
		public function setWordWrap($boolean:Boolean): void 
		{ 
			m_textField.wordWrap = $boolean;
			checkSize();
			update();
		}
		
		public function setInput($boolean:Boolean): void 
		{
			isInput = $boolean;
			if($boolean){
				this.mouseChildren = true;
				m_textField.selectable = true;
				m_textField.type = TextFieldType.INPUT;
				m_textField.addEventListener(Event.CHANGE, update);
				//System.useCodePage = true;
			} else{
				this.mouseChildren = false;
				m_textField.selectable = false;
				m_textField.type = TextFieldType.DYNAMIC;
				m_textField.removeEventListener(Event.CHANGE, update);
				//System.useCodePage = false;
			} 
		}
		 
		private function checkTyping(e:KeyboardEvent): void { }
		
		// size 와 관련있는 메서드
		public function setMultiLine($boolean:Boolean): void  {
			if(m_textField.multiline == $boolean) return ;
			m_textField.multiline = $boolean;
			checkSize();
			update();
		}
		// size 와 관련있는 메서드
		public function setSize($width:Number, $height:Number): void {
			m_textField.width = $width;
			m_textField.height = $height;
			checkSize();
			update();
		}
		
		public function getPadding(): Bound { return m_padding; }
		// size 와 관련있는 메서드
		public function setPadding($bound:Bound): void  {
			if(m_padding == $bound) return ;
			m_padding = $bound;
			checkSize();
			update();
		}
		
		public function getAutoSize(): String {
			return m_textField.autoSize;
		}
		// size 와 관련있는 메서드
		public function setAutoSize($textFieldAutoSize:String): void {
			if(m_textField.autoSize == $textFieldAutoSize) return ;
			m_textField.autoSize = $textFieldAutoSize;
			checkSize();
			update();
		}
		
		public function getLabel(): String { return m_textField.text; }
		// size 와 관련있는 메서드
		public function setLabel($text:String): void { 
			if(m_textField.text == $text) return ;
			if($text==null) $text = '';
			m_textField.text = $text;
			if(isOverRangeExpresstion) TextFieldUtil.overRangeEllipsisExpression(m_textField);
			checkSize();
			update();
		}
		
		public function getTextWidth(): Number { return m_textField.textWidth; }
		public function getTextHeight(): Number { return m_textField.textHeight; }
		
		public function getTextField(): TextField { return m_textField;}
		
		public function getScrollHPosition():Number { return (m_textField.scrollH-1/m_textField.maxScrollH-1); }
		public function setScrollHPosition(rate:Number): void 
		{
			m_textField.scrollH = int(m_textField.maxScrollH*rate);
		}
		
		public function getScrollVPosition():Number { return (m_textField.scrollV-1/m_textField.maxScrollV-1); }
		
		public function setScrollVPosition(rate:Number): void  {
			m_textField.scrollV = int(m_textField.maxScrollV*rate);
		}
		
		protected function checkSize(e:Event=null): void {
			m_textField.x = m_padding.getLeft();
			m_textField.y = m_padding.getTop();
			
			m_border.width = m_background.width = m_padding.getLeft()+m_textField.width+m_padding.getRight();
			m_border.height = m_background.height = m_padding.getTop()+m_textField.height+m_padding.getBottom();
		}
		
		public function update(e:Event=null): void {
			if(m_renderType == RenderType.BITMAP){
				m_textFieldBitmap.setSource(m_textField);
			}
			if(stage){
				m_border.update(e);
				m_background.update(e);
			}
			dispatchEvent(new Event(Event.CHANGE));
		}
		
		override public function get width():Number { return m_textField.width; }
		
		override public function set width($width:Number): void {
			m_textField.width = $width;
			checkSize();
			update();
		}
		
		override public function get height():Number { return m_textField.height; }
		
		override public function set height($height:Number): void {
			m_textField.height = $height;
			checkSize();
			update();
		}
		
		override public function get scaleX(): Number { return m_textField.scaleX; }
		
		override public function set scaleX($scaleX:Number): void {
			m_textField.scaleX = $scaleX;
			checkSize();
			update();
		}
		
		override public function get scaleY(): Number { return m_textField.scaleY; }
		
		override public function set scaleY($scaleY:Number): void {
			m_textField.scaleY = $scaleY;
			checkSize();
			update();
		}
		
		public function getVisibleLeftBorder():Boolean { return m_border.getVisibleLeft(); }
		public function setVisibleLeftBorder($bool:Boolean): void {
			m_border.setVisibleLeft($bool);
		}
		
		public function getVisibleTopBorder():Boolean { return m_border.getVisibleTop(); }
		public function setVisibleTopBorder($bool:Boolean): void {
			m_border.setVisibleTop($bool);
		}
		
		public function getVisibleRightBorder():Boolean { return m_border.getVisibleRight(); }
		public function setVisibleRightBorder($bool:Boolean): void {
			m_border.setVisibleRight($bool);
		}
		
		public function getVisibleBottomBorder():Boolean { return m_border.getVisibleBottom(); }
		public function setVisibleBottomBorder($bool:Boolean): void {
			m_border.setVisibleBottom($bool);
		}
		
		public function isEmptyLabel(): Boolean {
			return (getLabel() == '' || !getLabel());
		}
		
		public function toBitmapData(): BitmapData {
			m_textFieldBitmap.setSource(m_textField)
			return m_textFieldBitmap.toBitmapData();
		}
		
		
	}//c
}